#include "STL_MysqlConnPool.h"
#include <unistd.h>
#include <stdlib.h>

using namespace STL;

void executeQuery(std::string sql)
{
    long tid = -1;

    std::cout << "tid =[" << tid << "]" << std::endl;

    STL_Connection *conn;
    try
    {
        conn = STL_MysqlConnPool::getConnection();
    }
    catch (const std::exception &e)
    {
        std::cerr << e.what() << '\n';
    }
    if (!conn)
    {
        std::cout << "getConnection NULL pointer" << std::endl;
        exit(-1);
    }

    try
    {
        STL_QueryResult queryResult = conn->executeQuery(sql, tid);
    }
    catch (const std::exception &e)
    {
        std::cerr << e.what() << '\n';
    }

    try
    {
        STL_MysqlConnPool::releaseConnection(conn);
    }
    catch (const std::exception &e)
    {
        std::cerr << e.what() << '\n';
    }
}

void *handlerSelect(void *arg)
{
    long tid = (long)arg;

    std::cout << "tid =[" << tid << "]" << std::endl;
    STL_Connection *conn;
    try
    {
        conn = STL_MysqlConnPool::getConnection();
    }
    catch (const std::exception &e)
    {
        std::cerr << e.what() << '\n';
    }
    if (!conn)
    {
        std::cout << "getConnection NULL pointer" << std::endl;
        exit(-1);
    }

    //cout << "Connection.this:" << conn << endl;

    char *query;
    query = "SELECT * FROM `videorelay`.`test`";

    try
    {
        STL_QueryResult queryResult = conn->executeQuery(query, tid);
        for (int j = 0; j < queryResult.getColumnCount(); j++)
        {
            if (j == 0)
                std::cout << "|";
            std::cout << queryResult.getField(j) << "|";
        }
        std::cout << std::endl;
        for (int j = 0; j < queryResult.getColumnCount(); j++)
        {
            if (j == 0)
                std::cout << "|";
            std::cout << "---|";
        }
        std::cout << std::endl;
        for (int i = 0; i < queryResult.getRowCount(); i++)
        {
            for (int j = 0; j < queryResult.getColumnCount(); j++)
            {
                if (j == 0)
                    std::cout << "|";
                std::cout << queryResult.getElement(i, j) << "|";
            }
            std::cout << std::endl;
        }
    }
    catch (const std::exception &e)
    {
        std::cerr << e.what() << '\n';
    }
    try
    {
        STL_MysqlConnPool::releaseConnection(conn);
    }
    catch (const std::exception &e)
    {
        std::cerr << e.what() << '\n';
    }
}

int main(int argc, char *argv[])
{
    std::string host = "localhost";
    unsigned int port = 3306;
    std::string user = "root";
    std::string pass = "123";
    std::string dbname = "videorelay";
    int poolSize = 1;

    STL_MysqlConnPool::initPool(host, port, user, pass, dbname, poolSize);

    //删除表
    executeQuery("drop TABLE `test`;");
    // 创建表
    executeQuery("CREATE TABLE `videorelay`.`test` ( `id` INT NOT NULL AUTO_INCREMENT , `device_id` VARCHAR(32) NOT NULL , `transport_mode` ENUM('udp','tcp') NOT NULL , `create_time` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP , `update_time` TIMESTAMP on update CURRENT_TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP , PRIMARY KEY (`id`)) ENGINE = InnoDB;");

    executeQuery("INSERT INTO `videorelay`.`test` (`device_id`,`transport_mode`) VALUES (123,'udp');");
    executeQuery("INSERT INTO `videorelay`.`test` (`device_id`,`transport_mode`) VALUES (124,'tcp');");
    executeQuery("INSERT INTO `videorelay`.`test` (`device_id`,`transport_mode`) VALUES (125,'udp');");
    executeQuery("INSERT INTO `videorelay`.`test` (`device_id`,`transport_mode`) VALUES (126,'tcp');");
    executeQuery("INSERT INTO `videorelay`.`test` (`device_id`,`transport_mode`) VALUES (127,'udp');");

    handlerSelect(nullptr);

    executeQuery("UPDATE `videorelay`.`test` SET `transport_mode` = 'tcp'");

    handlerSelect(nullptr);

    executeQuery("delete from `videorelay`.`test` where device_id in(123,125);");

    handlerSelect(nullptr);

    int count = -1;
    if (argc > 1)
    {
        count = atoi(argv[1]);
    }
    if (count < 0)
    {
        count = 1;
    }
    else if (count > 10)
    {
        count = 10;
    }

    for (int i = 0; i < count; i++)
    {

        const int THREAD_COUNT = 1;
        pthread_t threads[THREAD_COUNT];

        for (long i = 0; i < THREAD_COUNT; i++)
        {
            pthread_create(&threads[i], NULL, handlerSelect, (void *)i);
            //sleep(1);
        }

        for (int i = 0; i < THREAD_COUNT; i++)
        {
            pthread_join(threads[i], 0);
        }

        std::cout << "==============================LOOPBACK=================================" << std::endl;
    }

    STL_MysqlConnPool::destroyPool();

    return 0;
}